<html>
<head>
  <title>C++编译过程</title>
  <basefont face="微软雅黑" size="2" />
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  <meta name="exporter-version" content="Evernote Windows/307027 (zh-CN, DDL); Windows/6.1.0 (Win32);"/>
  <style>
    body, td {
      font-family: 微软雅黑;
      font-size: 10pt;
    }
  </style>
</head>
<body>
<a name="691"/>
<h1>C++编译过程</h1>

<div>
<span><div><div><span><a href="http://www.cnblogs.com/dongdongweiwu/p/4743709.html">http://www.cnblogs.com/dongdongweiwu/p/4743709.html</a></span></div><ul><li><span>了解编译过程的益处</span></li><li><span>c++工程相关的问题</span></li><ul><li><span>什么是库？静态库和动态库又有什么区别？</span></li><li><span>头文件起什么作用？</span></li></ul></ul><div><br/></div><div><br/></div><div><br/></div><div><span><font style="font-size: 14pt; color: rgb(20, 113, 145);"><b>编译过程</b></font></span></div><div><br/></div><ul><li><span>名词：</span></li><ul><li><span>编译：把源文件中的源代码翻译成机器语言，保存到目标文件中。如果编译通过，就会把CPP转换成OBJ文件。</span></li><li><span><b><font style="color: rgb(227, 0, 0);">编译单元：</font></b></span></li><ul><li><span>每个cpp就是一个编译单元，每个编译单元相互之间是独立且相互不知的。一个编译单元（Translation Unit）是指一个.cpp文件以及这所include的所有.h文件，.h文件里面的代码将会被扩展到包含它的.cpp文件里，然后编译器编译该.cpp文件为一个.obj文件，后者拥有PE（Portable Executable，即Windows可执行文件）文件格式，并且本身包含的就是二进制代码，但是不一定能执行，因为并不能保证其中一定有main函数。当编译器将一个工程里的所有.cpp文件以分离的方式编译完毕后，再由链接器进行链接成为一个.exe或.dll文件。</span></li></ul><li><span>目标文件：编译后生成的文件，以机器码的形式包含了编译单元里所有的函数和数据、<span style="color: rgb(255, 0, 0); font-weight: bold;">导出符号表、未解决符号表、地址重定向表</span>等</span></li><ul><li>目标文件的类型：</li><ul><li>可重定位文件（.o、.obj文件）：<span style="font-size: 10.5pt; line-height: 1.5;">其中包含有适合于其它目标文件链接来创建一个可执行的或者</span><span style="font-size: 10.5pt; line-height: 1.5;">共享的目标文件的代码和数据。每个cpp会被编译成一个.o文件</span></li><li>共享的目标文件（库文件）</li><ul><li>这种文件存放了适合于在两种上下文里链接的代码和数据。</li><ul><li>第一种是链接程序（静态库）可把它与其它可重定位文件及共享的目标文件一起处理来创建另一个目标文件</li><ul><li>静态链接库实际上是一个目标文件的集合，其中的每个文件含有库中的一个或者一组相关函数的代码</li></ul><li><span style="font-size: 10.5pt; line-height: 1.5;">第二种是动态链接程序（动态库）将它与另一个可</span><span style="font-size: 10.5pt; line-height: 1.5;">执行文件及其它的共享目标文件结合到一起，创建一个进程映象</span></li><ul><li><span style="font-size: 10.5pt; line-height: 1.5;">动态链接库在程序执行时才被调用</span></li></ul></ul></ul><li>可执行文件</li><ul><li><span style="font-size: 10.5pt; line-height: 1.5;">一个可以被操作系统创建一个进程来执行之的文件</span></li></ul></ul><li>.o文件在编译后就能获得，但是库文件、可执行文件都需要在链接后才能获得</li></ul></ul><li><span style="line-height: 1.45;">c++程序编译过程图</span></li></ul><div><img src="C++编译过程_files/Image.jpg" type="image/jpeg" data-filename="Image.jpg" width="378"/></div><div><br/></div><div><font color="#1C3387" style="font-size: 14pt;"><b>各个文件的功能</b></font></div><div><span style="color: rgb(237, 28, 36);">resource.h就是.rc文件的头文件</span></div><div style="-en-paragraph: true; margin-top: 1em; margin-bottom: 1em;"><span style="-en-paragraph: true; color: rgb(237, 28, 36);">.rc文件里的常量全在resource.h定义</span></div><div><span style="-en-paragraph: true; color: rgb(237, 28, 36);">.rc文件和resource.h 都是给project add resource 的时候VS 自动生成的。</span></div><div><div><br/></div><table style="border-collapse: collapse; min-width: 100%;"><colgroup><col style="width: 164px;"></col><col style="width: 222px;"></col><col style="width: 409px;"></col></colgroup><tbody><tr><td style="border: 1px solid rgb(204, 204, 204); width: 164px; padding: 8px;"><div style="text-align: center;">文件名</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 222px; padding: 8px;"><div>文件功能</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 409px; padding: 8px;"><div>相关说明</div></td></tr><tr><td style="border: 1px solid rgb(204, 204, 204); width: 164px; padding: 8px;"><div><span style="color: rgb(237, 28, 36);">resource.h</span></div><div><font color="#ED1C24">.rc</font></div></td><td style="border: 1px solid rgb(204, 204, 204); width: 222px; padding: 8px;"><div>.rc的头文件，<font style="color: rgb(227, 0, 0);">定义.rc中的常量</font></div><div>资源文件，里面包括了引入的位图文件，窗口，图标，光标等等</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 409px; padding: 8px;"><div>.rc说白了就是一个文本文件（txt），配合.h文件使用。可以用VC创建，可以创建的内容有：menu\ico\bmp\string等。</div><div>resource.h一般不需要手动写：当添加一个资源时，VC会自动在resource.h文件中增加一个宏定义。<font style="color: rgb(227, 0, 0);">该定义确定资源的ID</font></div></td></tr><tr><td style="border: 1px solid rgb(204, 204, 204); width: 164px; padding: 8px;"><div>stdafx.h</div><div><br/></div><div>stdafx.cpp</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 222px; padding: 8px;"><div>stdafx.h : 标准系统包含文件的包含文件 </div><div>只包括标准包含文件的源文件</div><div><br/></div></td><td style="border: 1px solid rgb(204, 204, 204); width: 409px; padding: 8px;"><div>#include &lt;afxwin.h&gt;         // MFC 核心组件和标准组件</div><div>#include &lt;afxext.h&gt;         // MFC 扩展</div><div><br/></div><div>#ifndef _AFX_NO_OLE_SUPPORT</div><div>#include &lt;afxole.h&gt;         // MFC OLE 类</div><div>#include &lt;afxodlgs.h&gt;       // MFC OLE 对话框类</div><div>#include &lt;afxdisp.h&gt;        // MFC 自动化类</div><div>#endif // _AFX_NO_OLE_SUPPORT</div></td></tr><tr><td style="border: 1px solid rgb(204, 204, 204); width: 164px; padding: 8px;"><div>targetver.h</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 222px; padding: 8px;"><div>定义程序运行的环境</div><div>0×0500 表示Windows 2000</div><div>0×0501为Windows XP</div><div>0×0502为Windows Server 2003</div><div>0×0600 为 Windows Vista。</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 409px; padding: 8px;"><div>#ifndef WINVER                      //程序中没有定义WINVER宏时</div><div>#define WINVER 0x0600            // 定义WINVER为0x0600         </div><div>                                                //0x0600表示Windows Vista</div><div>#endif</div></td></tr><tr><td style="border: 1px solid rgb(204, 204, 204); width: 164px; padding: 8px;"><div>xxx_Dialog.h</div><div>xxx_Dialog.cpp</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 222px; padding: 8px;"><div>对话框</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 409px; padding: 8px;"><div>继承自CDialog类</div><div>消息处理程序</div><div>控件通知处理程序</div><div><br/></div></td></tr><tr><td style="border: 1px solid rgb(204, 204, 204); width: 164px; padding: 8px;"><div>view_Matrix.h</div><div>view_Matrix.cpp</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 222px; padding: 8px;">功能操作</td><td style="border: 1px solid rgb(204, 204, 204); width: 409px; padding: 8px;"><div><br/></div></td></tr><tr><td style="border: 1px solid rgb(204, 204, 204); width: 164px; padding: 8px;"><div>SwAddin1.rgs</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 222px; padding: 8px;"><div><br/></div></td><td style="border: 1px solid rgb(204, 204, 204); width: 409px; padding: 8px;"><div>registers your add-in with SolidWorks when it is compiled</div><div><br/></div></td></tr><tr><td style="border: 1px solid rgb(204, 204, 204); width: 164px; padding: 8px;"><div>BitmapHander.cpp</div><div>corresponding.h file</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 222px; padding: 8px;"><div>images for COM add-ins are bitmaps stored in the DLL as resources.</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 409px; padding: 8px;"><div>To use the BitmapHandler object, call CreateFileFromResourceBitmap <span style="line-height: 1.45;">and pass it the resource name of the image you want to retrieve.</span></div></td></tr><tr><td style="border: 1px solid rgb(204, 204, 204); width: 164px; padding: 8px;"><div>CSwAddin<span style="font-style: italic;">n</span>Dialog.cpp  corresponding .h file</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 222px; padding: 8px;"><div>to demonstrate compatibility with MFC</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 409px; padding: 8px;"><div><br/></div></td></tr><tr><td style="border: 1px solid rgb(204, 204, 204); width: 164px; padding: 8px;"><div>DocView.cpp and corresponding .h file</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 222px; padding: 8px;"><div><br/></div></td><td style="border: 1px solid rgb(204, 204, 204); width: 409px; padding: 8px;"><div>This file contains the definition of the DocView object. If an add-in <span style="line-height: 1.45;">is listening for ModelView events, then there is a DocView instance for </span><span style="line-height: 1.45;">each open ModelView.</span></div></td></tr><tr><td style="border: 1px solid rgb(204, 204, 204); width: 164px; padding: 8px;"><div>PMPageHandler.cpp  corresponding .h file</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 222px; padding: 8px;"><div>This file contains the class that implements the IPropertyManagerPage2Handler<span style="font-style: italic;">n</span> interface.</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 409px; padding: 8px;"><div>An instance of this object is passed to SolidWorks when creating a PropertyManager page. When a control on the page is manipulated, the corresponding function in this object is called.</div></td></tr><tr><td style="border: 1px solid rgb(204, 204, 204); width: 164px; padding: 8px;"><div>stdafx.cpp</div><div>corresponding .h file</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 222px; padding: 8px;"><div>This file contains the #import statements for the SolidWorks type libraries and any other necessary SolidWorks #include statements.</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 409px; padding: 8px;"><div><br/></div></td></tr><tr><td style="border: 1px solid rgb(204, 204, 204); width: 164px; padding: 8px;"><div>SwAddin<span style="font-style: italic;">n</span>.cpp  corresponding .h file</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 222px; padding: 8px;"><div><b><font style="color: rgb(227, 0, 0);">This is the main add-in file. It contains the implementation of the <span style="line-height: 1.45;">ISwAddin interface.</span></font></b></div></td><td style="border: 1px solid rgb(204, 204, 204); width: 409px; padding: 8px;"><div>entry and exit functions for this add-in.</div><div>also contains the user interface and SolidWorks event callback functions.</div></td></tr><tr><td style="border: 1px solid rgb(204, 204, 204); width: 164px; padding: 8px;"><div>SwAddin<span style="font-style: italic;">n</span>.def</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 222px; padding: 8px;"><div>This file declares DLL function exports.</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 409px; padding: 8px;"><div><br/></div></td></tr><tr><td style="border: 1px solid rgb(204, 204, 204); width: 164px; padding: 8px;"><div>SwAddin<span style="font-style: italic;">n</span>.idl</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 222px; padding: 8px;"><div>This file is used to generate the type library for the add-in.</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 409px; padding: 8px;"><div><br/></div></td></tr><tr><td style="border: 1px solid rgb(204, 204, 204); width: 164px; padding: 8px;"><div>SwAddin<span style="font-style: italic;">n</span>_module.cpp</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 222px; padding: 8px;"><div>Generated by Visual Studio, this file contains COM definitions for the DLL.</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 409px; padding: 8px;"><div><br/></div></td></tr><tr><td style="border: 1px solid rgb(204, 204, 204); width: 164px; padding: 8px;"><div>SwDocument.cpp  corresponding .h file</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 222px; padding: 8px;"><div><br/></div></td><td style="border: 1px solid rgb(204, 204, 204); width: 409px; padding: 8px;"><div>This file contains the CSwDocument class that handles events thrown <span style="line-height: 1.45;">by open model documents. There is an instance of this class for every </span><span style="line-height: 1.45;">open model <font style="color: rgb(173, 0, 0);"><b>document.</b></font></span></div></td></tr><tr><td style="border: 1px solid rgb(204, 204, 204); width: 164px; padding: 8px;"><div>UserPropertyManagerPage.cpp </div><div>corresponding .h file</div></td><td style="border: 1px solid rgb(204, 204, 204); width: 222px; padding: 8px;"><div>The function AddControls controls the layout of the PropertyManager <span style="line-height: 1.45;">page.</span></div></td><td style="border: 1px solid rgb(204, 204, 204); width: 409px; padding: 8px;"><div>This file contains the wrapper class for the SolidWorks IPropertyManagerPage2. A PropertyManager page allows you to extend the user interface for your add-in with standard buttons, check boxes, and so on.</div><div>All controls must be added to group boxes on the page. Group boxes are displayed in the order in which they are added. Controls in a group box are displayed in the order in which they are added to the group box.</div></td></tr></tbody></table><div><font style="color: rgb(28, 51, 135); font-size: 16pt;"><b>名词</b></font></div></div><h2><span style="font-weight: normal;"><font style="font-size: 12pt; color: rgb(28, 51, 135);">type library类型库</font></span></h2><div><span style="color: rgb(51, 51, 51); font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px;">type library 是 COM 技术中所谓的“类型库”，它的作用在于以一种和具体语言无关的方式说明 COM 组件中</span><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px;"><font style="color: rgb(227, 0, 0);">接口的定义</font></span><span style="color: rgb(51, 51, 51); font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px;">。一般而言，一个类型库由微软提供的工具 MIDL 从 IDL 描述文件生成出来，以一个 tlb 后缀名的文件的形式存在。使用 tlb 之前必须先注册。</span></div><div><br/></div><div><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px;"><font style="font-size: 12pt; color: rgb(28, 51, 135);">IDL:</font></span></div><div><span style="color: rgb(51, 51, 51); font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px; background-color: rgb(255, 255, 255);">IDL(Interface Definition Language)接口定义语言</span></div><div><span style="color: rgb(51, 51, 51); font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px; background-color: rgb(255, 255, 255);">是一种可读的基于文本的格式的文件。</span></div><div><span style="color: rgb(51, 51, 51); font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px; background-color: rgb(255, 255, 255);">IDL的语法像C,可以使用Microsoft IDL(MIDL)编译器来生成类型库。</span></div><div><br/></div><div><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px;"><font style="font-size: 12pt; color: rgb(28, 51, 135);">CLSID: </font></span></div><div><span style="color: rgb(51, 51, 51); font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px;">Class ID是GUID一个具体的类型的名称，注册表 HKEY_CLASSES_ROOT\CLSID </span></div><div><span style="color: rgb(51, 51, 51); font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px;">每个接口CLSID或GUID都代表一个COM接口的实现　</span></div><div><br/></div><div><font style="font-size: 14pt; color: rgb(28, 51, 135);"><b><a href="http://blog.csdn.net/qianchenglenger/article/details/21599235">一个简单的dll</a></b></font></div><div>一、在我们建立的工程中建立一个源码文件”dllmain.cpp“，在“dllmain.cpp”中，键入如下代码：</div><div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.14902); background-position: initial initial; background-repeat: initial initial;-en-codeblock:true;"><div><ol start="1"><li>#include &lt;Windows.h&gt;  </li><li>#include &lt;stdio.h&gt;  </li><li>  </li><li>BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)  </li><li>{  </li><li>    switch (ul_reason_for_call)  </li><li>    {  </li><li>    case DLL_PROCESS_ATTACH:  </li><li>        printf(&quot;DLL_PROCESS_ATTACH\n&quot;);  </li><li>        break;  </li><li>    case DLL_THREAD_ATTACH:  </li><li>        printf(&quot;DLL_THREAD_ATTACH\n&quot;);  </li><li>        break;  </li><li>    case DLL_THREAD_DETACH:  </li><li>        printf(&quot;DLL_THREAD_DETACH\n&quot;);  </li><li>        break;  </li><li>    case DLL_PROCESS_DETACH:  </li><li>        printf(&quot;DLL_PROCESS_DETACH\n&quot;);  </li><li>        break;  </li><li>    }  </li><li>    return TRUE;  </li><li>}  </li></ol></div></div><div>二、编译，我们直接编译，即可以在Debug文件夹下，找到我们生成的dll文件，“MyDLL.dll”，注意，代码里面的printf语句，并不是必须的，只是我们用于<a href="http://lib.csdn.net/base/softwaretest" style="color: #df3434; font-weight: bold;" title="软件测试知识库">测试</a>程序时使用。而DllMain函数，是dll的进入/退出函数。</div><div>三、线程调用DLL。有两种方式：隐式链接和显式链接。其目的均是将DLL的文件映像映射进线程的进程的地址空间。</div><div><font style="font-size: 14pt; color: rgb(28, 51, 135);"><b>隐式链接调用</b></font></div><div>隐士地链接是将DLL的文件影响<font style="color: rgb(227, 0, 0);"><b>映射到进程的地址空间中</b></font>最常用的方法。当链接一个应用程序时，必须制定要链接的一组LIB文件。每个LIB文件中包含了DLL文件允许应用程序（或另一个DLL）调用的函数的列表。<span style="-en-paragraph: true;">当链接器看到应用程序调用了某个DLL的LIB文件中给出的函数时，它就在生成的EXE文件映像中加入了信息，指出了包含函数的DLL文件的名称。当</span><a href="http://lib.csdn.net/base/operatingsystem" style="-en-paragraph: true; color: #df3434; font-weight: bold;" title="操作系统知识库">操作系统</a><span style="-en-paragraph: true;">加载EXE文件时，系统查看EXE文件映像的内容来看要装入哪些DLL，而后试图将需要的DLL文件映像映射到进程的地址空间中。当寻找DLL时，系统在系列位置查找文件映像。</span></div><ul><li>1.包含EXE映像文件的目录</li><li>2.进程的当前目录</li><li>3.Windows系统的目录</li><li>4.Windows目录</li><li>5.列在PATH环境变量中的目录</li></ul><div><span style="-en-paragraph: true;">这种方法，一般都是在程序链接时控制，反映在链接器的配置上，网上大多数讲的各种库的配置，比如OPENGL或者</span><a href="http://lib.csdn.net/base/opencv" style="-en-paragraph: true; color: #df3434; font-weight: bold;" title="OpenCV知识库">OpenCV</a><span style="-en-paragraph: true;">等，都是用的这种方法</span></div></div><div><br/></div><div><span style="font-size: 14pt; color: rgb(28, 51, 135); font-weight: bold;">显式链接调用</span></div><div><span style="-en-paragraph: true;">两种函数：加载函数</span></div><div style="box-sizing: border-box; padding: 8px; font-family: Monaco, Menlo, Consolas, &quot;Courier New&quot;, monospace; font-size: 12px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; background-color: rgb(251, 250, 248); border: 1px solid rgba(0, 0, 0, 0.14902); background-position: initial initial; background-repeat: initial initial;-en-codeblock:true;"><div>HINSTANCE LoadLibrary(LPCTSTR lpszLibFile);  </div><div><span style="line-height: 1.45;">HINSTANCE LoadLibraryEx(LPCSTR lpszLibFile,HANDLE hFile,DWORD dwFlags);  </span></div></div><div>返回值HINSTANCE值指出了文件映像映射的虚拟内存地址。如果DLL不能被映进程的地址空间，函数就返回NULL。</div><div><span style="-en-paragraph: true;"><font style="font-size: 14pt; color: rgb(28, 51, 135);"><b>显式释放DLL</b></font></span></div><div>在显式加载DLL后，在任意时刻可以调用FreeLibrary函数来显式地从进程的地址空间中解除该文件的映像。</div><div><span style="-en-paragraph: true;"><br/></span></div><div><span style="-en-paragraph: true;"><br/></span></div><div><span style="-en-paragraph: true;"><br/></span></div><div><br/></div></span>
</div></body></html> 